import 'dart:async';
import 'dart:convert';

import 'package:chathouse/constant/app_constant.dart';
import 'package:chathouse/model/member_info.dart';
import 'package:chathouse/public/Config.dart';
import 'package:chathouse/util/log.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/status.dart' as status;
import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:convert' as convert;
import '../public/event_bus.dart';

class MyWebSocketChannel {
  MyWebSocketChannel._webSocketChannel();

  static final MyWebSocketChannel _instance =
      MyWebSocketChannel._webSocketChannel();

  static MyWebSocketChannel get instance {
    return _instance;
  }

  IOWebSocketChannel? _channel;
  Timer? _timer;
  MemberInfo? memberInfo;

  void initSocket() {
    try {
      Object? json = SpUtil.getObject2(AppConstant.memberInfo);
      if (json == null) {
        return;
      }
      memberInfo = MemberInfo.fromJson2(json);
      String url = "wss://noahsolutions.net/chathouse-api/websocket/${memberInfo?.data?.membersNo}";
      LogUtil.d("用户连接编号 - -  - - - - - - - - - - $url");
      if (_channel != null) {
        dispose();
      }
      _channel = IOWebSocketChannel.connect(Uri.parse(url),
          connectTimeout: const Duration(seconds: 30),
          pingInterval: const Duration(seconds: 30));
      _channel?.stream.listen(onData,
          onError: onError,
          onDone: onDone(),
          cancelOnError: true); //设置错误时取消订阅);
      // sendHeartPacket();
    } catch (e) {
      // initSocket();
    }
    startCountdownTimer();
  }

  void startCountdownTimer() {
    const oneSec = Duration(seconds: 20);
    callback(timer) {
      if (_channel != null) {
        sendHeartPacket();
      }
    }

    _timer = Timer.periodic(oneSec, callback);
  }

  var messageReceived = false; //是否收到心跳消息

  ///发送心跳包
  void sendHeartPacket() {
    messageReceived = false;
    final map = {
      "msgtype": "0",
    };
    MyWebSocketChannel.instance.sendMessage(convert.jsonEncode(map));
    // 计时器，10秒后执行指定的代码
     Future.delayed(const Duration(seconds: 10), () {
      if (!messageReceived) {
        // 没有收到消息，执行相应的操作
        LogUtil.d('10秒都沒收到服務端發回來的pong消息...開始重連webSocket');
        // 重新连接服务器等操作
        initSocket();
      }
    });
  }

  /**
   * @desc WebSocket心跳包
   * @author Marinda
   * @date 2022/9/26
   */
  void heartPacket() {
    //自定义Bool，判断是否Socket开启状态
    // if (state.socketStatus) {
    //自定义重连时间间隔
    // hearTimer = Timer(Duration(seconds: state.socketClienTime),() async{
    //   //  重新连接
    //   reconnectSocket();
    // });
    // sendHeartPacket();
    // }
  }

  // 发送消息

  void sendMessage(map) {
    _channel?.sink.add(map);
  }

  // 断连，然后执行重连
  onDone() {
    LogUtil.d("服务器....onDone .... : ");
    // initSocket();
  }

  // 错误日志
  onError(err) {
    WebSocketChannelException ex = err;
    LogUtil.d("服务器连接错误: ${ex.message}");
  }

  // 接受数据，数据json字符串????，然后转成Map????
  onData(event) {
    LogUtil.d('收到服务器发来的消息:' + event);
    Map<String, dynamic> map = json.decode(event);
    String msgtype = map["msgtype"] ?? "";
    if (msgtype == "0") {
      // 处理心跳消息
      messageReceived = true;
    }else{
      eventBus.fire(OnMsgUpdate(map));
      eventBus.fire(UpdateClientMsgListEvent(needLoading: false));
    }
  }

  void dispose() {
    LogUtil.d("WebSocket dispose");
    _channel?.sink.close(status.goingAway);
    _timer?.cancel();
  }
}
